#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
主题:过滤序列元素
问题: 你有一个数据序列，想利用一些规则从中提取出需要的值或者是缩短序列
提示 : 
    1. 列表推导和生成器表达式通常情况下是过滤数据最简单的方式
"""
mylist = [1, 4, -5, 10, -7, 2, 3, -1]
print(f"{mylist = }")

def recipe1():
    """最简单的过滤序列元素的方法就是使用列表推导"""
    positivelist = [n for n in mylist if n > 0]
    negativelist = [n for n in mylist if n < 0]
    print(f"{positivelist = }")
    print(f"{negativelist = }")


def recipe2():
    """使用生成器表达式迭代产生过滤的元素, 占用内存更少"""
    pos = (n for n in mylist if n > 0)
    for x in pos:
        print(f"{x = }")


def recipe3():
    """过滤规则比较复杂: 使用内建的 filter() 函数"""
    values = ['1', '2', '-3', '-', '4', 'N/A', '5']
    # # filter() 返回的一个迭代器
    int_vals = list(filter(is_int, values))
    print(f"{int_vals = }")

    for val in filter(is_int, values):
        print(f"{val = }")


def recipe4():
    """过滤的时候转换数据"""
    import math
    positivelist = [math.sqrt(n) for n in mylist if n > 0]
    print(f"{positivelist = }")


def recipe5():
    """过滤操作的一个变种就是将不符合条件的值用新的值代替，而不是丢弃它们"""
    clip_neg = [n if n > 0 else 0 for n in mylist]
    print(f"{clip_neg = }")
    clip_pos = [n if n < 0 else 0 for n in mylist]
    print(f"{clip_pos = }")

def recipe6():
    """过滤工具 itertools.compress()"""
    from itertools import compress

    addresses = [
        '5412 N CLARK',
        '5148 N CLARK',
        '5800 E 58TH',
        '2122 N CLARK',
        '5645 N RAVENSWOOD',
        '1060 W ADDISON',
        '4801 N BROADWAY',
        '1039 W GRANVILLE',
    ]
    print(f"{addresses = }")
    counts = [ 0, 3, 10, 4, 1, 7, 6, 1]
    print(f"{counts = }")

    more5 = [n > 5 for n in counts]
    print(f"{more5 = }")

    # compress() 返回的一个迭代器
    for item in compress(addresses, more5):
        print(f"{item = }")

def is_int(val):
    try:
        int(val)
        return True
    except ValueError:
        return False


def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()
    print('recipe3'.center(20, '*'))
    recipe3()
    print('recipe4'.center(20, '*'))
    recipe4()
    print('recipe5'.center(20, '*'))
    recipe5()
    print('recipe6'.center(20, '*'))
    recipe6()    


if __name__ == '__main__':
    main()
